// Copyright (c) 2025 Huawei Technologies Co., Ltd.
// openUBMC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//         http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Description: VMM虚拟媒体客户端

#ifndef VMM_CLIENT_HPP
#define VMM_CLIENT_HPP

#include <string>
#include "WebSocketClient.hpp"
#include "AuthenticationManager.hpp"
#include "VMMMessage.hpp"
#include "PackData.hpp"
#include "Defines.hpp"
#include "ScsiProcessor.hpp"
#include "ImageDevice.hpp"

enum class ConnectState {
    INIT = 0x00, 
    CERTIFY,
    CONNECT,
    ACTIVE
};

class VmmClient : public WebSocketClient {
public:
    VmmClient();
    ~VmmClient() override;

    void SetErrorHandler(std::function<void(const std::exception&)> handler);
    void SetCloseHandler(std::function<void(const uint16_t&)> handler);
    void SetLogHandler(std::function<void(const std::string&)> handler);
    void LogMessage(const std::string& message);

    int OpenVmm(const std::string& filePath, MountType type, std::string host, uint16_t port, const char* token);
    int CloseVmm();

protected:
    void OnMessage(const std::string& message) override;
    void OnClose(const websocket::close_reason& cr) override;
    void OnError(const std::exception& error) override;

private:
    std::function<void(const std::exception&)> errorHandler_;               // 错误处理回调函数
    std::function<void(const websocket::close_reason&)> closeHandler_;      // 会话关闭处理回调函数
    std::function<void(const std::string&)> logHandler_;                    // 日志处理回调函数

    void ProcessAck(uint8_t sack);
    void ProcessClose(uint8_t status);
    void CreateDevice(uint8_t deviceType);

    std::mutex openVmmMutex_; // 防止 OpenVmm 重入
    std::mutex connectRspMutex_; // 用于同步 OpenVmm 和 ProcessConnectRsp
    std::condition_variable connectRspCv_; // 条件变量，用于等待 ProcessConnectRsp 的结果
    int connectRsp_ = E_ERR; // 存储服务端返回的结果

    std::unique_ptr<ImageDevice> imageDevice_; // 处理大容量存储设备的类
    std::unique_ptr<ScsiProcessor> scsiProcessor_; // 处理SCSI命令的类
    bool isConnected_ = false; // 是否已连接
    ConnectState connectState_ = ConnectState::INIT; // 连接状态
    std::string filePath_; // 文件路径
    MountType mountType_; // 挂载类型
};

#endif  // VMM_CLIENT_HPP